﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Yottamud_2013_v3_Main.Game_Files
{
    class GameResources
    {
        public static ResourceTypes.ClassType[] ClassList { get; set; }
        public static ResourceTypes.RaceType[] RaceList { get; set; }
        public static ResourceTypes.ShopType[] ShopList { get; set; }
        public static Dictionary<int, ResourceTypes.NpcType> NpcList { get; set; }
        public static ResourceTypes.RoomType[] RoomList { get; set; }
        public static Dictionary<int, ResourceTypes.ItemType> ItemList { get; set; }
        public static ResourceTypes.SpellType[] SpellList { get; set; }
        private string _dbFileName = "";
        public static Dictionary<int, string> AbilityList = new Dictionary<int, string>();
        public static List<int> ErrorNumbers = new List<int>();

        public enum Source
        {
            Database,
            XML

        }

        public GameResources(string dbFileName)
        {
            _dbFileName = dbFileName;

            LoadAbilityList();
            LoadItemList(Source.Database);
            LoadSpellList();
            LoadNPCList();
            LoadShopList();
            LoadRaceList();
            LoadRoomList();
            LoadClassList();
        }

        #region Load Process
        
        private void LoadRaceList()
        {
            RaceList = ResourceCollector.LoadRaceFromDB(_dbFileName);
        }

        private void LoadClassList()
        {
            ClassList = ResourceCollector.LoadClassFromDB(_dbFileName);

        }

        private void LoadAbilityList()
        {
            AbilityList.Clear();

            AbilityList.Add(0,"None");
            AbilityList.Add(1,"Damage");
            AbilityList.Add(2,"Armor Class");
            AbilityList.Add(3,"Resist Cold");
            AbilityList.Add(4,"Max Damage");
            AbilityList.Add(5,"Resist Fire");
            AbilityList.Add(6,"Enslave");
            AbilityList.Add(7,"Damage Reduction");
            AbilityList.Add(8,"Drain Life");
            AbilityList.Add(9,"Shadow");
            AbilityList.Add(10,"Armor Class (from Blur)");
            AbilityList.Add(11,"Energy Level");
            AbilityList.Add(12,"Summon");
            AbilityList.Add(13,"Illumination");
            AbilityList.Add(14,"Room Illumination");
            AbilityList.Add(15,"Alterhunger");
            AbilityList.Add(16,"Alterthirst");
            AbilityList.Add(17,"Damage(-MR)");
            AbilityList.Add(18,"Heal");
            AbilityList.Add(19,"Poison");
            AbilityList.Add(20,"Cure Poison");
            AbilityList.Add(21,"Immunity to Poison");
            AbilityList.Add(22,"Accuracy");
            AbilityList.Add(23,"Affects Undead Only");
            AbilityList.Add(24,"Protection from Evil");
            AbilityList.Add(25,"Protection from Good");
            AbilityList.Add(26,"Detect Magic");
            AbilityList.Add(27,"Stealth");
            AbilityList.Add(28,"Magical");
            AbilityList.Add(29,"Punch");
            AbilityList.Add(30,"Kick");
            AbilityList.Add(31,"Bash");
            AbilityList.Add(32,"Smash Quest");
            AbilityList.Add(33,"Killblow");
            AbilityList.Add(34,"Dodge");
            AbilityList.Add(35,"JumpKick");
            AbilityList.Add(36,"Magic Resistance");
            AbilityList.Add(37,"Picklocks");
            AbilityList.Add(38,"Tracking");
            AbilityList.Add(39,"Thievery");
            AbilityList.Add(40,"FindTraps");
            AbilityList.Add(41,"DisarmTraps");
            AbilityList.Add(42,"Learn Spell");
            AbilityList.Add(43,"Cast Spell");
            AbilityList.Add(44,"Intelligence");
            AbilityList.Add(45,"Wisdom");
            AbilityList.Add(46,"Strength");
            AbilityList.Add(47,"Health");
            AbilityList.Add(48,"Agility");
            AbilityList.Add(49,"Charm");
            AbilityList.Add(50,"MageBaneQuest");
            AbilityList.Add(51,"AntiMagic");
            AbilityList.Add(52,"EvilInCombat");
            AbilityList.Add(53,"BlindingLight");
            AbilityList.Add(54,"IlluTarget");
            AbilityList.Add(55,"AlterGeneralLightDuration");
            AbilityList.Add(56,"RechargeItem");
            AbilityList.Add(57,"SeeHidden");
            AbilityList.Add(58,"Crits");
            AbilityList.Add(59,"ClassOk");
            AbilityList.Add(60,"Fear");
            AbilityList.Add(61,"AffectExit");
            AbilityList.Add(62,"EvilChance");
            AbilityList.Add(63,"Experience");
            AbilityList.Add(64,"AddCP");
            AbilityList.Add(65,"Resist Stone");
            AbilityList.Add(66,"Resist Lightning");
            AbilityList.Add(67,"Quickness");
            AbilityList.Add(68,"Slowness");
            AbilityList.Add(69,"Maximum Mana");
            AbilityList.Add(70,"Spell Casting");
            AbilityList.Add(71,"Confusion");
            AbilityList.Add(72,"Damage Shield");
            AbilityList.Add(73,"Dispell Magic");
            AbilityList.Add(74,"HoldPerson");
            AbilityList.Add(75,"Paralyze");
            AbilityList.Add(76,"Mute");
            AbilityList.Add(77,"Perception");
            AbilityList.Add(78,"Animal");
            AbilityList.Add(79,"MageBind");
            AbilityList.Add(80,"AffectsAnimalsOnly");
            AbilityList.Add(81,"Freedom");
            AbilityList.Add(82,"Cursed");
            AbilityList.Add(83,"CURSED");
            AbilityList.Add(84,"Rcrs");
            AbilityList.Add(85,"Shatter");
            AbilityList.Add(86,"Quality");
            AbilityList.Add(87,"Speed");
            AbilityList.Add(88,"Alter HP");
            AbilityList.Add(89,"Punch Accuracy");
            AbilityList.Add(90,"Kick Accuracy");
            AbilityList.Add(91,"JumpKick Accuracy");
            AbilityList.Add(92,"Punch Damage");
            AbilityList.Add(93,"Kick Damage");
            AbilityList.Add(94,"Jump Kick Damage");
            AbilityList.Add(95,"Slay");
            AbilityList.Add(96,"Encumbrance");
            AbilityList.Add(97,"Good Only");
            AbilityList.Add(98,"Evil Only");
            AbilityList.Add(99,"AlterDRpercent");
            AbilityList.Add(100,"LoyalItem");
            AbilityList.Add(101,"");
            AbilityList.Add(102,"RaceStealth");
            AbilityList.Add(103,"ClassStealth");
            AbilityList.Add(104,"DefenseModifier");
            AbilityList.Add(105,"Accuracy");
            AbilityList.Add(106,"Accuracy");
            AbilityList.Add(107,"BlindUser");
            AbilityList.Add(108,"AffectsLivingOnly");
            AbilityList.Add(109,"NonLiving");
            AbilityList.Add(110,"NotGood");
            AbilityList.Add(111,"NotEvil");
            AbilityList.Add(112,"NeutralOnly");
            AbilityList.Add(113,"NotNeutral");
            AbilityList.Add(114,"%Spell");
            AbilityList.Add(115, "");
            AbilityList.Add(116,"Backstab Accuracy");
            AbilityList.Add(117,"Backstab Minimum Damage");
            AbilityList.Add(118,"Backstab Maximum Damage");
            AbilityList.Add(119,"Del@Maint");
            AbilityList.Add(120, "");
            AbilityList.Add(121,"Recharge");
            AbilityList.Add(122,"RemovesSpell");
            AbilityList.Add(123,"Hit Point Regeneration");
            AbilityList.Add(124,"NegateAbility");
            AbilityList.Add(125,"Ice Sorceress Quest");
            AbilityList.Add(126,"Good Alignment Quest");
            AbilityList.Add(127,"Neutral Alignment Quest");
            AbilityList.Add(128,"Evil Alignment Quest");
            AbilityList.Add(129,"High Druid Quest");
            AbilityList.Add(130,"Champion of Blood Quest");
            AbilityList.Add(131,"Adult Red Dragon Quest");
            AbilityList.Add(132,"Wererat Quest");
            AbilityList.Add(133,"Phoenix Feather Quest");
            AbilityList.Add(134,"Dao Lord Quest");
            AbilityList.Add(135,"MinLevel");
            AbilityList.Add(136,"MaxLevel");
            AbilityList.Add(137,"Shock");
            AbilityList.Add(138,"RoomVisible");
            AbilityList.Add(139,"SpellImmu");
            AbilityList.Add(140,"TeleportRoom");
            AbilityList.Add(141,"TeleportMap");
            AbilityList.Add(142,"HitMagic");
            AbilityList.Add(143,"ClearItem");
            AbilityList.Add(144,"");
            AbilityList.Add(145,"ManaRgn");
            AbilityList.Add(146,"MonsGuards");
            AbilityList.Add(147,"ResistWater");
            AbilityList.Add(148,"TextBlock");
            AbilityList.Add(149,"Remove@Maint");
            AbilityList.Add(150,"HealMana");
            AbilityList.Add(151,"EndCast");
            AbilityList.Add(152,"Rune");
            AbilityList.Add(153,"KillSpell");
            AbilityList.Add(154,"Visible@Maint");
            AbilityList.Add(155,"DeathText");
            AbilityList.Add(156,"QuestItem");
            AbilityList.Add(157,"ScatterItems");
            AbilityList.Add(158,"ReqToHit");
            AbilityList.Add(159,"KaiBind");
            AbilityList.Add(160,"GiveTempSpell");
            AbilityList.Add(161,"OpenDoor");
            AbilityList.Add(162,"Lore");
            AbilityList.Add(163,"SpellComponent");
            AbilityList.Add(164,"EndCast%");
            AbilityList.Add(165,"AlterSpDmg");
            AbilityList.Add(166,"AlterSpLength");
            AbilityList.Add(167,"UnEquipItem");
            AbilityList.Add(168,"EquipItem");
            AbilityList.Add(169,"CannotWearLocation");
            AbilityList.Add(170,"Sleep");
            AbilityList.Add(171,"Invisibility");
            AbilityList.Add(172,"SeeInvisible");
            AbilityList.Add(173,"Scry");
            AbilityList.Add(174,"StealMana");
            AbilityList.Add(175,"StealHPtoMP");
            AbilityList.Add(176,"StealMPtoHP");
            AbilityList.Add(177,"SpellColours");
            AbilityList.Add(178,"Shadowform");
            AbilityList.Add(179,"FindTrapsValue");
            AbilityList.Add(180,"PickLocksValue");
            AbilityList.Add(181,"GHouseDeed");
            AbilityList.Add(182,"GHouseTax");
            AbilityList.Add(183,"GHouseItem");
            AbilityList.Add(184,"GShopItem");
            AbilityList.Add(185,"BadAttk");
            AbilityList.Add(186,"Super Stealth");
            AbilityList.Add(187,"Meditate");
            AbilityList.Add(1001,"Grant Thievery");
            AbilityList.Add(1002,"Grant Traps");
            AbilityList.Add(1003,"Grant Picklocks");
            AbilityList.Add(1004,"Grant Tracking");
            AbilityList.Add(1100,"Anti Magic Not Ok");
            AbilityList.Add(1101,"Meets Req to Hit");
            AbilityList.Add(1102,"UseSpell");
        }

        public void LoadItemList(Source iSource)
        {

            switch (iSource)
            {
                case Source.XML:

                    break;

                case Source.Database:

                    if (ItemList != null)
                    {
                        ItemList.Clear();
                    }
                    ItemList = ResourceCollector.LoadItemFromDB(_dbFileName, false);

                    break;
            }
        }

        public void LoadShopList()
        {

            ShopList = ResourceCollector.LoadShopFromDB(_dbFileName);

        }
        public void LoadSpellList()
        {
            SpellList = null;

            SpellList = ResourceCollector.LoadSpellFromDB(_dbFileName, false);

        }

        public void LoadNPCList()
        {
            NpcList = ResourceCollector.LoadNpcFromDB(_dbFileName, false);
        }



        public void LoadRoomList()
        {
            RoomList = ResourceCollector.LoadRoomFromDB(_dbFileName, false);
        }

        #endregion

        #region Search Functions

        public static ResourceTypes.ShopType FindShop(int shopID)
        {

            return Array.Find(ShopList, shop => shop.ShopNumber == shopID);

        }

        public static ResourceTypes.SpellType FindSpell(int iNumber)
        {
            return Array.Find(SpellList, spell => spell.Number == iNumber);
        }

        public static ResourceTypes.SpellType FindSpell(string iName)
        {
            return Array.Find(SpellList, spell => spell.Name.ToLower() == iName.ToLower());
        }

        public static ResourceTypes.ItemType FindItem(string iName)
        {
            if (iName != null)
            {
                foreach (KeyValuePair<int, ResourceTypes.ItemType> kp in ItemList)
                {
                    if (kp.Value.Name.ToLower() == iName.ToLower())
                    {
                        return kp.Value;
                    }
                }
            }
            return null;
        }

        public static string BuildDropList(ResourceTypes.NpcType iNpc)
        {
            string droppedItems = "";

            foreach (ResourceTypes.ItemType item in iNpc.DroppedItems)
            {
                droppedItems += item.Name + ", ";

            }

            return droppedItems;

        }

        public static string BuildAbilityList(ResourceTypes.ItemType iItem)
        {
            string abilityDesc = "";

            foreach (ResourceTypes.AbilityType ability in iItem.Abilities)
            {

                switch (ability.AbilityID)
                {
                    case 43:
                        abilityDesc += ability.AbilityName + " " + FindSpell(ability.AbilityValue).Name + ", ";
                        break;
                    case 42:
                        abilityDesc += ability.AbilityName + " " + FindSpell(ability.AbilityValue).Name + ", ";
                        break;
                    default:
                        abilityDesc += ability.AbilityName + " " + ability.AbilityValue + ", ";
                        break;
                }
                
            }

            return abilityDesc;
        }

        public static string BuildSpellList(ResourceTypes.NpcType iNpc)
        {
            string spellListing = "";

            foreach (ResourceTypes.SpellType spell in iNpc.SpellList)
            {
                spellListing += spell.Name + ", ";
            }

            return spellListing;
        }

        public static ResourceTypes.ItemType FindItem(int iNumber)
        {
            try
            {
                return ItemList[iNumber];
            }
            catch 
            {
                ErrorNumbers.Add(iNumber);
                return null; 
            }
        }

        public static List<string> FindExits(ResourceTypes.RoomType iRoom)
        {
            List<string> exits = new List<string>();

            if (iRoom.DirectionNorth.Length > 1 && !iRoom.DirectionNorth.Contains("Text"))
            {
                exits.Add("north");
            }
            if (iRoom.DirectionSouth.Length > 1 && !iRoom.DirectionSouth.Contains("Text"))
            {
                exits.Add("south");
            }
            if (iRoom.DirectionEast.Length > 1 && !iRoom.DirectionEast.Contains("Text"))
            {
                exits.Add("east");
            }
            if (iRoom.DirectionWest.Length > 1 && !iRoom.DirectionWest.Contains("Text"))
            {
                exits.Add("west");
            }
            if (iRoom.DirectionNorthEast.Length > 1 && !iRoom.DirectionNorthEast.Contains("Text"))
            {
                exits.Add("northeast");
            }
            if (iRoom.DirectionNorthWest.Length > 1 && !iRoom.DirectionNorthWest.Contains("Text"))
            {
                exits.Add("northwest");
            }
            if (iRoom.DirectionSouthEast.Length > 1 && !iRoom.DirectionSouthEast.Contains("Text"))
            {
                exits.Add("southeast");
            }
            if (iRoom.DirectionSouthWest.Length > 1 && !iRoom.DirectionSouthWest.Contains("Text"))
            {
                exits.Add("southwest");
            }
            if (iRoom.DirectionUp.Length > 1 && !iRoom.DirectionUp.Contains("Text"))
            {
                exits.Add("up");
            }
            if (iRoom.DirectionDown.Length > 1 && !iRoom.DirectionDown.Contains("Text"))
            {
                exits.Add("down");
            }

            return exits;
        }

        private static bool VerifyRoomExits(List<string> exitOne, List<string> exitTwo)
        {
          
            try
            {
                if (exitOne.Count == exitTwo.Count)
                {
                    for (int eIndex = 0; eIndex < exitOne.Count; eIndex++ )
                    {
                        if (!exitOne[eIndex].Contains(exitTwo[eIndex]))
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    return false;
                }
            }
            catch { }

            return true;

        }

        public static bool VerifyRoomNPC(List<ResourceTypes.NpcType> iList, int npcNumber)
        {
            bool status = false;

            if (iList.Count != 0 && npcNumber != 0)
            {
                foreach (ResourceTypes.NpcType npc in iList)
                {
                    if (npcNumber == npc.Number)
                    {
                        status = true;
                    }
                }
            }
            else
            {
                status = true;

            }
            return status;
        }
        public static ResourceTypes.RoomType FindRoom(string name, List<string> exits, List<ResourceTypes.NpcType> npcs)
        {
            List<ResourceTypes.RoomType> foundRooms = new List<ResourceTypes.RoomType>();

            foreach (ResourceTypes.RoomType room in RoomList)
            {
                if (room.RoomName == name)
                {
                    List<string> exitsFound = FindExits(room);

                    if (exitsFound.Count == exits.Count)
                    {
                        bool eStatus = VerifyRoomExits(exits, exitsFound);
                        bool nStatus = true;//VerifyRoomNPC(npcs, room.NpcID);

                        if (eStatus && nStatus)
                        {
                            return room;
                        }
                    }
                }
            }

            
            return null;
        }
        public static ResourceTypes.RoomType FindRoom(string name)
        {
            return Array.Find(RoomList, rm => rm.RoomName.ToLower() == name.ToLower());
        }

        public static ResourceTypes.RoomType FindRoom(int map, int room)
        {
            return Array.Find(RoomList, rm => rm.MapNumber == map && rm.RoomNumber == room);
        }

        public static string FindAbility(int iAbility)
        {
            return AbilityList[iAbility];
        }
        public static ResourceTypes.NpcType FindNPC(int iNumber)
        {
            return NpcList[iNumber];
        }

        public static ResourceTypes.NpcType FindNPC(string iName)
        {
            foreach (KeyValuePair<int, ResourceTypes.NpcType> kp in NpcList)
            {
                if (kp.Value.Name.ToLower() == iName.ToLower())
                {
                    return kp.Value;
                }
            }

            return null;
        }

        #endregion

    }
}
